/**
* \file		SousArbre.c
* \brief	Code des fonctions du module SousArbre
* \details	C'est ici qu'est le code des accesseurs, mutateurs ainsi que
*		la fonction de test vérifant le bon fonctionnement du module
*		SousArbre.
*		Une description de la structure SousArbre est fournie à
*		la rubrique \link SousArbre.h
*/

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "SousArbre.h"


/*========================== Gestion de la mémoire ==========================*/

void initSousArbre(SousArbre *pSA, int nbBr)
{
   int i;
   setNbBranchesSousArbre(pSA, nbBr);
   pSA->tabDeb = (Technologie **)malloc(nbBr * sizeof(Technologie*));

   for(i=0; i<nbBr; i++)
	{
	   setIemeTabDebSousArbre(pSA, NULL, i);
	}
}

void creerSousArbre(SousArbre **ppSA, int nbBr)
{
   *ppSA = (SousArbre*)malloc(sizeof(SousArbre));
   initSousArbre(*ppSA, nbBr);
}

void libereSousArbre(SousArbre *pSA)
{
   int i,nbBr = getnbBranchesSousArbre(pSA);
   Technologie *ptech, *ptech2;

   /* Libération de l'espace occupé par les technologies */
   for(i=0; i<nbBr; i++)
	{
	   ptech = getDebBrancheSousArbre(pSA, i);

	   while(ptech != NULL)
		{
		   ptech2 = getTechSuivTech(ptech);
		   detruireTech(ptech);
		   ptech = ptech2;
		}
	   setIemeTabDebSousArbre(pSA, NULL, i);
	}
   free(pSA->tabDeb);
}

void detruireSousArbre(SousArbre *pSA)
{
   libereSousArbre(pSA);
   free(pSA);
}


/*====================== Fonctions de Montage des SA ======================*/

void ajouteTechBrancheSousArbre(SousArbre *pSA, Technologie *ptech)
{
   int numBranche;
   numBranche = getNumBrancheTech(ptech);

   if(NULL != getDebBrancheSousArbre(pSA, numBranche))
	{
	   setTechSuivTech(ptech, getDebBrancheSousArbre(pSA, numBranche));
	}

   setIemeTabDebSousArbre(pSA, ptech, numBranche);

}

void creerDepuisFichierSousArbre(SousArbre **pSA, FILE *f)
{
   char chaine[200];
   char descr[400];
   int nb,i, nbBranches, nbTest, nbPrer, nbDebloquees;
   Technologie *pnouvTech;

   fscanf(f, "%d\n", &nbBranches);

   creerSousArbre(pSA, nbBranches);

   for(nbTest = 0; nbTest < nbBranches; nbTest++)
	{
	 /* Récupération de l'ID */
	   fscanf(f, "%d\n", &nb);

	 /* Récupération du nom */
	   fgets(chaine, sizeof chaine, f);

	 /* Récupération de la description */
	   fgets(descr, sizeof descr, f);

	 /* Récupération du nombre de technologies nécessaires */
	   fscanf(f, "%d\n", &nbPrer);

    /* Récupération du nombre de technologies débloquées */
	   fscanf(f, "%d\n", &nbDebloquees);

	 /* Création de la Technologie en cours de chargement */
	   creerTech(&pnouvTech, chaine, descr, nbPrer, nbDebloquees);

	 /* Mise en place de l'ID */
	   setIDTech(pnouvTech, nb);

	 /* Coût de la Technologie */
	   for(i=0; i<4; i++)
		{
		   fscanf(f, "%d\n", &nb);
		   setTabCoutTech(pnouvTech, nb, i);
		}

	 /* Bonus apportés par la Technologie */
	   for(i=0; i<8; i++)
		{
		   fscanf(f, "%d\n", &nb);
		   setTabBonusTech(pnouvTech, nb, i);
		}


	 /* Malus apportés par la Technologie */
	   for(i=0; i<8; i++)
		{
		   fscanf(f, "%d\n", &nb);
		   setTabMalusTech(pnouvTech, nb, i);
		}


		if(nbPrer > 0)
			{
			   for(i=0; i<nbPrer; i++)
				{
				   fscanf(f, "%d\n", &nb);
				   setTabPrerTech(pnouvTech, nb, i);
				}
			}
		else
			{
			   fscanf(f, "%d\n", &nb);
			}

		if(nbDebloquees > 0)
			{
			   for(i=0; i<nbDebloquees; i++)
				{
				   fscanf(f, "%d\n", &nb);
				   setTabIDTechDebloqueesTech(pnouvTech, nb, i);
				}
			}
		else
			{
			   fscanf(f, "%d\n", &nb);
			}

	 /* Ajout de la technologie à la branche */
	   ajouteTechBrancheSousArbre(*pSA, pnouvTech);
	}
}

/*============================= Accesseurs =============================*/

int getnbBranchesSousArbre(const SousArbre *pSA)
{
   return pSA->nbBranches;
}

Technologie *getTechSousArbre(const SousArbre *pSA, int IDTech)
{
   int branche = getNumBrancheDepuisIDTech(IDTech);
   Technologie *ptech;
   ptech = getDebBrancheSousArbre(pSA, branche);

   while(NULL != ptech)
	{
	   if(IDTech == getIDTech(ptech))
		{
		   return ptech;
		}
	   ptech = getTechSuivTech(ptech);
	}

   /* Si on est sorti du while sans rien retourner, c'est que l'ID n'existe
      pas */
   printf("Technologie inconnue\n");
   return NULL;
}

Technologie *getDebBrancheSousArbre(const SousArbre *pSA, int numBr)
{
   if(numBr >= getnbBranchesSousArbre(pSA))
	{
	   return NULL;
	}
   else
	{
	   return pSA->tabDeb[numBr];
	}

}
/*============================= Mutateurs =============================*/

void setNbBranchesSousArbre(SousArbre *pSA, int nouvNb)
{
   pSA->nbBranches = nouvNb;
}

void setIemeTabDebSousArbre(SousArbre *pSA, Technologie *nouvTech, int numCase)
{
   pSA->tabDeb[numCase] = nouvTech;
}

/*=========================== Fonctions de Test ===========================*/


/* à mettre dans affichage pour avoir les différentes infos désirées */
/*
		   printf("ID : %d\n", getIDTech(pnouvTech));

		   printf("nb de tech nécessaires : %d\n", getNbPrerequisProdTech(pnouvTech));
	   	   printf("Bois : %d\n", getCoutBoisTech(pnouvTech));
		   printf("Metal : %d\n", getCoutMetalTech(pnouvTech));
		   printf("Biere : %d\n", getCoutBiereTech(pnouvTech));
		   printf("Nourriture : %d\n", getCoutNourritureTech(pnouvTech));

		   printf("\n");

		   printf("Attaque : %d\n", getBonusAttaqueTech(pnouvTech));
		   printf("Défense : %d\n", getBonusDefenseTech(pnouvTech));
		   printf("Fécondité : %d\n", getBonusFeconditeTech(pnouvTech));
		   printf("Mortalité : %d\n", getBonusMortaliteTech(pnouvTech));
		   printf("Emigration : %d\n", getBonusEmigrationTech(pnouvTech));
		   printf("Immigration : %d\n", getBonusImmigrationTech(pnouvTech));
		   printf("Moral : %d\n", getBonusMoralTech(pnouvTech));
		   printf("Production : %d\n", getBonusProdTech(pnouvTech));

		   printf("\n");

		   printf("Malus Attaque : %d\n", getMalusAttaqueTech(pnouvTech));
		   printf("Malus Défense : %d\n", getMalusDefenseTech(pnouvTech));
		   printf("Malus Fécondité : %d\n", getMalusFeconditeTech(pnouvTech));
		   printf("Malus Mortalité : %d\n", getMalusMortaliteTech(pnouvTech));
		   printf("Malus Emigration : %d\n", getMalusEmigrationTech(pnouvTech));
		   printf("Malus Immigration : %d\n", getMalusImmigrationTech(pnouvTech));
		   printf("Malus Moral : %d\n", getMalusMoralTech(pnouvTech));
		   printf("Malus Production : %d\n", getMalusProdTech(pnouvTech));

		   printf("\n");

if(nbPrer > 0)
	{
	   tabTest = getTabPrerequisProdTech(pnouvTech);
	   for(j=0; j<nbPrer; j++)
		{
		   printf("ID technologie nécessaire : %d\n", tabTest[j].IDTech);
		}

	}
else
	{
	   printf("pas de tech nécessaire\n");
	}



*/
/* à supprimer */
void affSousArbre(SousArbre *pSA)
{
   int i,nbBr = getnbBranchesSousArbre(pSA);
   Technologie *pnouvTech;
/*   int j, nbPrer;
   Prerequis *tabTest;*/



   for(i=0; i<nbBr; i++)
	{
	   pnouvTech = getDebBrancheSousArbre(pSA, i);

	   while(pnouvTech != NULL)
		{
/*		   nbPrer = getNbPrerequisProdTech(pnouvTech);*/
		   printf("Nom : %s", getNomTech(pnouvTech));
		   printf("Description : %s", getDescriptionTech(pnouvTech));



		   pnouvTech = getTechSuivTech(pnouvTech);
		}
	}
}

void testTousChampsTechAccessibles(const SousArbre *pSA)
{
   int i,nbBr = getnbBranchesSousArbre(pSA);
   Technologie *pnouvTech;
   int j, nbPrer;


   for(i=0; i<nbBr; i++)
	{
	   pnouvTech = getDebBrancheSousArbre(pSA, i);

	   while(pnouvTech != NULL)
		{
		   nbPrer = getNbPrerequisProdTech(pnouvTech);
		   getNbTechDebloqueesTech(pnouvTech);

		   getNomTech(pnouvTech);
		   getDescriptionTech(pnouvTech);
		   getIDTech(pnouvTech);

		   getNbPrerequisProdTech(pnouvTech);
	   	   getCoutBoisTech(pnouvTech);
		   getCoutMetalTech(pnouvTech);
		   getCoutBiereTech(pnouvTech);
		   getCoutNourritureTech(pnouvTech);

		   getBonusAttaqueTech(pnouvTech);
		   getBonusDefenseTech(pnouvTech);
		   getBonusFeconditeTech(pnouvTech);
		   getBonusMortaliteTech(pnouvTech);
		   getBonusEmigrationTech(pnouvTech);
		   getBonusImmigrationTech(pnouvTech);
		   getBonusMoralTech(pnouvTech);
		   getBonusProdTech(pnouvTech);

		   getMalusAttaqueTech(pnouvTech);
		   getMalusDefenseTech(pnouvTech);
		   getMalusFeconditeTech(pnouvTech);
		   getMalusMortaliteTech(pnouvTech);
		   getMalusEmigrationTech(pnouvTech);
		   getMalusImmigrationTech(pnouvTech);
		   getMalusMoralTech(pnouvTech);
		   getMalusProdTech(pnouvTech);


		   if(nbPrer > 0)
			{
			   for(j=0; j<nbPrer; j++)
				{
				   getIDIemePrerequisTech(pnouvTech, j);
				}
			}

/*           if(nbDebl > 0)
           {
               for(j=0; j<nbDebl; j++)
               {
                   getIemeIDTechDebloqueeTech(pnouvTech, j);
                   getIemeTechDebloqueeTech(pnouvTech, j);
               }
           }
*/
		   pnouvTech = getTechSuivTech(pnouvTech);
		}
	}

}

void testSousArbre()
{
   SousArbre *pSA;
   SousArbre *pSA2;
   SousArbre *pSA3;

   FILE* f;

   char adresse[100] = "./data/DatTech";

   /* récupération des données du fichier */
   f = fopen(adresse, "r");
   if(f == NULL)
	{
	   printf("Erreur lors de l'ouverture du fichier de données de l'arbre des technologies.\n");
	   assert(f);
	}

   printf("\nTest de SousArbre\n");

   printf("\tCréation de sous-arbres et ajout d'éléments\t");
   creerDepuisFichierSousArbre(&pSA,f);
   creerDepuisFichierSousArbre(&pSA2,f);
   creerDepuisFichierSousArbre(&pSA3,f);
   fclose(f);

   printf("OK\n");

   printf("\tAccessibilité des champs des technologies\t");
   testTousChampsTechAccessibles(pSA);
   testTousChampsTechAccessibles(pSA2);
   testTousChampsTechAccessibles(pSA3);
   printf("OK\n");

/*   affSousArbre(pSA);
   affSousArbre(pSA2);
   affSousArbre(pSA3);
*/
   detruireSousArbre(pSA);
   detruireSousArbre(pSA2);
   detruireSousArbre(pSA3);
}

